#include <stdio.h>

//创建一个函数，输入一个二维数组的某一行，将这行从大到小排序
void sort(int *p, int n)
{
    int i, j, temp;
    for (i = 0; i < n - 1; i++)
    {
        for (j = 0; j < n - 1 - i; j++)
        {
            if (p[j] < p[j + 1])
            {
                temp = p[j];
                p[j] = p[j + 1];
                p[j + 1] = temp;
            }
        }
    }
}

int main(int argc, char const *argv[])
{
    int m = 0, n = 0;
    scanf("%d %d", &m, &n);
    int num[m][n]; //用来排序的数组

    //输入二维数组
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            scanf("%d", &num[i][j]);
        }
    }

    //定义一个num2，将num的每一行都复制到num2中
    int num2[m][n]; //用来保存排序前的数组
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            num2[i][j] = num[i][j];
        }
    }

    for (int i = m - 1; i > 0; i--)
    {
        sort(num[i], n);     //将num1的最后一行排序
        int max = num[i][0]; //得到最后一行的最大值
        for (int j = 0; j < n; j++)
        {
            if (num2[i][j] == max) //如果倒数第二行的下方一行(最后一行)的第j个数正好是最大值
            {
                num[i - 1][j] += num[i][1];     //将最后一行的第二大的数加到倒数第二行的第j个数上
                num2[i - 1][j] = num[i - 1][j]; //保留排序前的数组
            }
            else
            {
                num[i - 1][j] += max;           //将最后一行的最大值加到倒数第二行的第j个数上
                num2[i - 1][j] = num[i - 1][j]; //保留排序前的数组
            }
        }
    }
    sort(num2[0], n);         //将排序前的数组的第一行排序
    printf("%d", num2[0][0]); //得到最大值
}